import React, { Component } from 'react'
// 新版本的生命周期钩子 16.3 版本以后
// 初始化  ---  挂载阶段
// 运行时  ---  更新时阶段
// 销毁
export default class App extends Component {
  // 1. 挂载阶段 - 设置初始化状态 以及 定义事件
  // 如果不初始化 state 或不进行方法绑定，则不需要为 React 组件实现构造函数
  // 在 constructor() 函数中不要调用 setState() 方法
  constructor (props) {
    super(props)
    this.state = { count: 100 }
  }
  // 2. 挂载阶段 - 一般也没什么用
  // 5. 更新时阶段
  // componentWillMount () {} ---- 废弃
  // getDerivedStateFromProps 会在调用 render 方法之前调用，
  // 并且在初始挂载及后续更新时都会被调用。
  // 它应返回一个对象来更新 state，如果返回 null 则不更新任何内容。
  // state 的值在任何时候都取决于 props
  static getDerivedStateFromProps (props, state) {}

  // 3.挂载阶段 - 初次渲染函数
  // 7.更新时阶段 - 更新视图
  // render() 方法是 class 组件中唯一必须实现的方法
  // 当 render 被调用时，它会检查 this.props 和 this.state 的变化，变化更新视图
  render() {
    return (
      <div>
        { this.state.count }
      </div>
    )
  }
  // 4.挂载阶段 - 组件初次加载完毕 - mounted - 数据请求/实例化/定时器/计时器/DOM操作
  // 会在组件挂载后（插入 DOM 树中）立即调用。依赖于 DOM 节点的初始化应该放在这里。
  // 如需通过网络请求获取数据，此处是实例化请求的好地方。
  componentDidMount () {}

  // 5.更新时阶段 - 组件即将接收到新的数据 --- watch --- 子组件监听到父组件的数据变化 - 用的不多
  // componentWillReceiveProps () {} ---- 废弃

  // 6.更新时阶段 - 提升react 性能的关键，必须填写返回值，返回值为true，才能实现视图的二次渲染
  // 根据 shouldComponentUpdate() 的返回值，
  // 判断 React 组件的输出是否受当前 state 或 props 更改的影响。
  // 默认行为是 state 每次发生变化组件都会重新渲染。大部分情况下，你应该遵循默认行为。
  shouldComponentUpdate (nextProps, nextState) {
    return true
  }

  // 7.更新时阶段 --- 组件即将更新 --- 没什么用
  // componentWillUpdate () {} --- 废弃

  // 8.更新时阶段 --- 并不常用
  // 在最近一次渲染输出（提交到 DOM 节点）之前调用。
  // 它使得组件能在发生更改之前从 DOM 中捕获一些信息（例如，滚动位置）
  getSnapshotBeforeUpdate (prevProps, prevState) {}

  // 9.更新时阶段 --- 组件更新完毕
  // 会在更新后会被立即调用。首次渲染不会执行此方法。
  // 当组件更新后，可以在此处对 DOM 进行操作。
  // 如果你对更新前后的 props 进行了比较，也可以选择在此处进行网络请求。
  componentDidUpdate (prevProps, prevState, snapshot) {}

  // 10.销毁阶段
  // 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作，
  // 例如，清除 timer，取消网络请求或清除在 componentDidMount() 中创建的订阅等
  componentWillUnmount () {}

  // 11.错误异常
  // 此生命周期在后代组件抛出错误后被调用。 它接收两个参数
  // error —— 抛出的错误。
  // info —— 带有 componentStack key 的对象，其中包含有关组件引发错误的栈信息。

  componentDidCatch (error, info) {}

  // 12.错误异常
  // 此生命周期会在后代组件抛出错误后被调用。 
  // 它将抛出的错误作为参数，并返回一个值以更新 state
  static getDerivedStateFromError (error) {}
}
